package com.example.oms.manager;

import com.example.oms.entity.Patients;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.time.LocalDate;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.Map;
import java.util.Random;
import java.util.concurrent.ConcurrentHashMap;

@Component
public class DailyQueueManager {
    //日期 -> 医生Id -> 时间段 -> 队列
    private final Map<LocalDate, Map<Integer, Map<String,LinkedList<Patients>>>> dailyDoctorPeriodQueue = new ConcurrentHashMap<>();
    private final Map<LocalDate, Map<Integer, Map<String,LinkedList<Patients>>>> suspendQueue = new ConcurrentHashMap<>();
DailyQueueManager(){
    initializeDailyQueues();
}
    //每天凌晨初始化当天队列、清理过期队列
    @Scheduled(cron = "0 0 0 * * ?")
    public void initializeDailyQueues() {
        // 获取当天的日期
        LocalDate today = LocalDate.now();
        System.out.println("当前日期："+today);
        // 清空过期的队列
        dailyDoctorPeriodQueue.clear();
        suspendQueue.clear();
        System.out.println("过期队列已清理");
        // 初始化当天医生队列
        dailyDoctorPeriodQueue.put(today, new ConcurrentHashMap<>());
        System.out.println("今日医生队列已初始化");
        // 初始化挂起队列
        suspendQueue.put(today, new ConcurrentHashMap<>());
        System.out.println("今日挂起队列已初始化");
    }

    //医生登录，初始化医生队列,初始化挂起队列
    public void initDoctorPeriodQueue(int doctorId) {
        LocalDate now = LocalDate.now();
        // 如果为空就新建一个map
        dailyDoctorPeriodQueue.computeIfAbsent(now, k -> new HashMap<>());

        Map<Integer, Map<String,LinkedList<Patients>>> doctorPeriodQueues = dailyDoctorPeriodQueue.get(now);
        doctorPeriodQueues.putIfAbsent(doctorId, new ConcurrentHashMap<>());
        System.out.println(doctorId+"医生：队列初始化成功");

        // 如果为空就新建一个map
        suspendQueue.computeIfAbsent(now, k -> new ConcurrentHashMap<>());

        Map<Integer, Map<String,LinkedList<Patients>>> suspendQueues = suspendQueue.get(LocalDate.now());
        suspendQueues.putIfAbsent(doctorId, new ConcurrentHashMap<>());
        System.out.println(doctorId+"医生：挂起队列初始化成功");
    }

    //初始化时间段队列
    public void initPeriodQueue(int doctorId,String period) {
        initDoctorPeriodQueue(doctorId); // 确保医生队列已存在
        Map<String,LinkedList<Patients>> periodQueue = dailyDoctorPeriodQueue.get(LocalDate.now()).get(doctorId);
        periodQueue.putIfAbsent(period, new LinkedList<>());
        System.out.println(period+"时间段：队列初始化成功");
        Map<String,LinkedList<Patients>> suspendQueues = suspendQueue.get(LocalDate.now()).get(doctorId);
        suspendQueues.putIfAbsent(period, new LinkedList<>());
        System.out.println(period+"时间段：阻塞队列初始化成功");
    }

    //预约患者入队
    public int addPatientToQueue(int doctorId, Patients patient, int isReserved, String period) {
        initPeriodQueue(doctorId,period);// 确保时间段队列已存在
        LinkedList<Patients> queue = dailyDoctorPeriodQueue.get(LocalDate.now()).get(doctorId).get(period);

        if (isReserved == 1) {
            int randomIndex = new Random().nextInt(8) + 3; // 3~10 随机位置
            queue.add(Math.min(randomIndex, queue.size()), patient);
        } else {
            queue.add(patient);
        }
        System.out.println("患者"+patient.getId()+"被加入到"+doctorId+"医生的"+period+"队列中");
        return getPatientPosition(doctorId,patient.getId(),period);

    }
    //挂起患者入队（解挂）
    public int unSuspend(int doctorId, Patients patient, String period) {
        LinkedList<Patients> suspendQueues = suspendQueue.get(LocalDate.now()).get(doctorId).get(period);
        suspendQueues.remove(patient);
        LinkedList<Patients> queue = dailyDoctorPeriodQueue.get(LocalDate.now()).get(doctorId).get(period);
        int randomIndex = new Random().nextInt(5); // 0~4 随机位置
        queue.add(Math.min(randomIndex, queue.size()), patient);
        System.out.println("解挂患者"+patient.getId()+"被加入到"+doctorId+"医生的"+period+"队列中");
        return getPatientPosition(doctorId,patient.getId(),period);
    }

    //查询患者在队列的位置
    public int getPatientPosition(int doctorId, int patientId, String period) {
        LinkedList<Patients> queue = dailyDoctorPeriodQueue.get(LocalDate.now()).get(doctorId).get(period);
        if (queue != null) {
            for (int i = 0; i < queue.size(); i++) {
                if (queue.get(i).getId() == patientId) {
                    return i + 1;
                }
            }
        }
        return -1;
    }

    //获取根据医生id获取问诊队列(旧，待废弃)
    public LinkedList<Patients> getQueue(int doctorId){
        return null;
    }

    //获取当天医生所有时间段的队列(新)
    public Map<String,LinkedList<Patients>> getQueues(int doctorId){
        return dailyDoctorPeriodQueue
                .get(LocalDate.now())
                .get(doctorId);
    }

    //获取挂起队列
    public Map<String,LinkedList<Patients>> getSuspendQueue(int doctorId){
        return suspendQueue
                .get(LocalDate.now())
                .get(doctorId);
    }

    //医生叫号(获取某时间段的队首，不移除)
    public Patients callNextPatient(int doctorId, String period) {
        LinkedList<Patients> queue = dailyDoctorPeriodQueue.get(LocalDate.now()).get(doctorId).get(period);
        if (queue != null && !queue.isEmpty()) {
            return queue.getFirst();
        }
        return null;
    }

    //确认患者到达，移除队首
    public Patients confirm(int doctorId, String period) {
        LinkedList<Patients> queue = dailyDoctorPeriodQueue.get(LocalDate.now()).get(doctorId).get(period);
        if (queue != null && !queue.isEmpty()) {
            return queue.removeFirst();
        }
        return null;
    }

    //挂起（患者未到达,挂起队首）
    public Patients suspend(int doctorId, String period){
        LinkedList<Patients> queue = dailyDoctorPeriodQueue.get(LocalDate.now()).get(doctorId).get(period);
        LinkedList<Patients> suspendQueues = suspendQueue.get(LocalDate.now()).get(doctorId).get(period);
        if (queue != null && !queue.isEmpty()) {
            Patients patient = queue.removeFirst();
            suspendQueues.add(patient);
            return patient;
        }
        return null;
    }
}

